home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Programming / vbcc / main.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  21KB  |  572 lines

  1. /*  $VER: vbcc (main.c) V0.4    */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int endok=1;
  8. int line,errors;
  9.  
  10. char *multname[]={"","s"};
  11. void raus(void)
  12. /*  Beendet das Programm                                            */
  13. {
  14.     if(DEBUG) printf("raus()\n");
  15.     if(!endok) printf("unexpected end of file\n");
  16.     if(errors) printf("%d error%s found!\n",errors,multname[errors>1]);
  17.     while(nesting>=0) leave_block();
  18.     if(in[0]&&(c_flags[17]&USEDFLAG)) fclose(in[0]);
  19.     cleanup_cg(out);
  20.     if(ppout) fclose(ppout);
  21.     if(out) fclose(out);
  22.     if(ic1) fclose(ic1);
  23.     if(ic2) fclose(ic2);
  24.     if(!(c_flags[17]&USEDFLAG)) pp_free();
  25.     if(endok&&!errors) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE);
  26. }
  27.  
  28. int eof;
  29.  
  30. void translation_unit(void)
  31. /*  bearbeitet translation_unit                                     */
  32. /*  hier z.Z. nur provisorisch                                      */
  33. {
  34.     while(1){
  35.         killsp();
  36.         if(c_flags[18]&USEDFLAG){
  37.             if(*s==EOF) raus();
  38.             fputs(string,ppout);fputc('\n',ppout);
  39.             s=string;*s=0;
  40.         }else{
  41.             if(eof||(!isalpha((unsigned char)*s)&&*s!='_')){
  42.                 if(!eof) error(0);
  43.                 raus();
  44.             }
  45.             endok=0;
  46.             var_declaration();
  47.             endok=1;
  48.         }
  49.     }
  50. }
  51.  
  52. void dontwarn(char *p)
  53. /*  schaltet flags fuer Meldung auf DONTWARN    */
  54. {
  55.     int i;
  56.     if(*p!='=') error(4,"-dontwarn");
  57.     i=atoi(p+1);
  58.     if(i>=err_num) error(159,i);
  59.     if(i<0){
  60.         for(i=0;i<err_num;i++)
  61.             if(!(err_out[i].flags&(ANSIV|FATAL)))
  62.                 err_out[i].flags|=DONTWARN;
  63.         return;
  64.     }
  65.     if(err_out[i].flags&(ANSIV|FATAL)) error(160,i);
  66.     err_out[i].flags|=DONTWARN;
  67. }
  68. void warn(char *p)
  69. /*  schaltet Warnung fuer Meldung ein           */
  70. /*  wenn Nummer<0 sind alle Warnungen ein       */
  71. {
  72.     int i;
  73.     if(*p!='=') error(4,"-warn");
  74.     i=atoi(p+1);
  75.     if(i>=err_num) error(159,i);
  76.     if(i<0){
  77.         for(i=0;i<err_num;i++) err_out[i].flags&=~DONTWARN;
  78.         return;
  79.     }else err_out[i].flags&=~DONTWARN;
  80. }
  81.  
  82. extern char *copyright;
  83.  
  84. int main(int argc,char *argv[])
  85. {
  86.     int i,j,fname=0;
  87.     c_flags_val[9].f=dontwarn;
  88.     c_flags_val[10].f=warn;
  89.     for(i=1;i<argc;i++){
  90.         if(*argv[i]!='-'){  /*  kein Flag   */
  91.             if(fname){
  92.                 error(1);
  93.             }else fname=i;
  94.         }else{
  95.             int flag=0;
  96.             for(j=0;j<MAXCF&&flag==0;j++){
  97.                 size_t l;
  98.                 if(!c_flags_name[j]) continue;
  99.                 l=strlen(c_flags_name[j]);
  100.                 if(l>0&&!strncmp(argv[i]+1,c_flags_name[j],l)){
  101.                     flag=1;
  102.                     if((c_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
  103.                     c_flags[j]|=USEDFLAG;
  104.                     if(c_flags[j]&STRINGFLAG){
  105.                         if(argv[i][l+1]!='='){error(3,argv[i]);}
  106.                         if(argv[i][l+2]||i>=argc-1)
  107.                             c_flags_val[j].p=&argv[i][l+2];
  108.                         else
  109.                             c_flags_val[j].p=&argv[++i][0];
  110.                     }
  111.                     if(c_flags[j]&VALFLAG){
  112.                         if(argv[i][l+1]!='='){error(4,argv[i]);}
  113.                         if(argv[i][l+2]||i>=argc-1)
  114.                             c_flags_val[j].l=atol(&argv[i][l+2]);
  115.                         else
  116.                             c_flags_val[j].l=atol(&argv[++i][0]);
  117.                     }
  118.                     if(c_flags[j]&FUNCFLAG) c_flags_val[j].f(&argv[i][l+1]);
  119.                 }
  120.             }
  121.             for(j=0;j<MAXGF&&flag==0;j++){
  122.                 size_t l;
  123.                 if(!g_flags_name[j]) continue;
  124.                 l=strlen(g_flags_name[j]);
  125.                 if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){
  126.                     flag=1;
  127.                     if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
  128.                     g_flags[j]|=USEDFLAG;
  129.                     if(g_flags[j]&STRINGFLAG){
  130.                         if(argv[i][l+1]!='='){error(3,argv[i]);}
  131.                         if(argv[i][l+2]||i>=argc-1)
  132.                             g_flags_val[j].p=&argv[i][l+2];
  133.                         else
  134.                             g_flags_val[j].p=&argv[++i][0];
  135.                     }
  136.                     if(g_flags[j]&VALFLAG){
  137.                         if(argv[i][l+1]!='='){error(4,argv[i]);}
  138.                         if(argv[i][l+2]||i>=argc-1)
  139.                             g_flags_val[j].l=atol(&argv[i][l+2]);
  140.                         else
  141.                             g_flags_val[j].l=atol(&argv[++i][0]);
  142.                     }
  143.                     if(g_flags[j]&FUNCFLAG) g_flags_val[j].f(&argv[i][l+1]);
  144.                 }
  145.             }
  146.             if(!flag){error(5,argv[i]);}
  147.         }
  148.     }
  149.     if(!(c_flags[6]&USEDFLAG)){
  150.       printf("%s\n",copyright);
  151.       printf("%s\n",cg_copyright);
  152.     }
  153.     if(!(c_flags[17]&USEDFLAG)) pp_init();
  154.     if(!(c_flags[8]&USEDFLAG)) c_flags_val[8].l=10; /* max. Fehlerzahl */
  155.     if(c_flags[22]&USEDFLAG) c_flags[7]|=USEDFLAG;   /*  iso=ansi */
  156.     if(c_flags[7]&USEDFLAG) error(209);
  157.     if(c_flags[0]&USEDFLAG) optflags=c_flags_val[0].l;
  158.     if(c_flags[11]&USEDFLAG) maxoptpasses=c_flags_val[11].l;
  159.     if(c_flags[12]&USEDFLAG) inline_size=c_flags_val[12].l;
  160.     if(c_flags[21]&USEDFLAG) fp_assoc=1;
  161.     if(c_flags[25]&USEDFLAG) unroll_size=c_flags_val[25].l;
  162.     if(c_flags[23]&USEDFLAG) noaliasopt=1;
  163.     if(!fname){error(6);}
  164.     inname=argv[fname];
  165.     strncpy(errfname,inname,FILENAME_MAX);    /*  das hier ist Muell - wird noch geaendert    */
  166.     if(!init_cg()) exit(EXIT_FAILURE);
  167.     if(c_flags[24]&USEDFLAG) multiple_ccs=0;
  168.     if(c_flags[17]&USEDFLAG){
  169.         in[0]=fopen(inname,"r");
  170.         if(!in[0]) {error(7,inname);}
  171.     }else{
  172.         if(!pp_include(inname)) error(7,inname);
  173.     }
  174.     if(!(c_flags[18]&USEDFLAG)&&!(c_flags[5]&USEDFLAG)){
  175.         if(c_flags[1]&USEDFLAG){
  176.             out=open_out(c_flags_val[1].p,0);
  177.         }else{
  178.             out=open_out(inname,"asm");
  179.         }
  180.         if(!out){
  181.             if(c_flags[17]&USEDFLAG){
  182.                 fclose(in[0]);
  183.             }else{
  184.                 pp_free();
  185.             }
  186.             exit(EXIT_FAILURE);
  187.         }
  188.     }
  189.     if(c_flags[2]&USEDFLAG) ic1=open_out(inname,"ic1");
  190.     if(c_flags[3]&USEDFLAG) ic2=open_out(inname,"ic2");
  191.     if(c_flags[18]&USEDFLAG) ppout=open_out(inname,"i");
  192.     if(c_flags[4]&USEDFLAG) DEBUG=c_flags_val[4].l; else DEBUG=0;
  193.     switch_count=0;break_label=0;
  194.     *string=0;s=string;line=0;
  195.     killsp();
  196.     nesting=-1;enter_block();
  197.     translation_unit();
  198. }
  199. int mcmp(const char *s1,const char *s2)
  200. /*  Einfachere strcmp-Variante.     */
  201. {
  202.     char c;
  203.     do{
  204.         c=*s1++;
  205.         if(c!=*s2++) return(1);
  206.     }while(c);
  207.     return(0);
  208. }
  209. void cpbez(char *m,int check_keyword)
  210. /*  Kopiert den naechsten Bezeichner von s nach m. Wenn check_keyord!=0 */
  211. /*  wird eine Fehlermeldung ausgegeben, falls das Ergebnis ein          */
  212. /*  reserviertes Keyword von C ist.                                     */
  213. {
  214.     char *p=m,*last=m+MAXI-1;int warned=0;
  215.     if(DEBUG&128) printf("Before cpbez:%s\n",s);
  216.     while(isalpha((unsigned char)*s)||isdigit((unsigned char)*s)||*s=='_'){
  217.         if(m<last){
  218.             *m++=*s++;
  219.         }else{
  220.             s++;
  221.             if(!warned){
  222.                 error(206,MAXI-1);
  223.                 warned=1;
  224.             }
  225.         }
  226.     }
  227.     *m=0;
  228.     if(DEBUG&128) printf("After cpbez:%s\n",s);
  229.     if(check_keyword){
  230.         char *n=p+1;
  231.         switch(*p){
  232.         case 'a': if(!mcmp(n,"uto")) error(216,p);
  233.                   return;
  234.         case 'b': if(!mcmp(n,"reak")) error(216,p);
  235.                   return;
  236.         case 'c': if(!mcmp(n,"ase")) error(216,p);
  237.                   if(!mcmp(n,"har")) error(216,p);
  238.                   if(!mcmp(n,"onst")) error(216,p);
  239.                   if(!mcmp(n,"ontinue")) error(216,p);
  240.                   return;
  241.         case 'd': if(!mcmp(n,"efault")) error(216,p);
  242.                   if(!mcmp(n,"o")) error(216,m);
  243.                   if(!mcmp(n,"ouble")) error(216,p);
  244.                   return;
  245.         case 'e': if(!mcmp(n,"lse")) error(216,p);
  246.                   if(!mcmp(n,"num")) error(216,p);
  247.                   if(!mcmp(n,"xtern")) error(216,p);
  248.                   return;
  249.         case 'f': if(!mcmp(n,"loat")) error(216,p);
  250.                   if(!mcmp(n,"or")) error(216,p);
  251.                   return;
  252.         case 'g': if(!mcmp(n,"oto")) error(216,p);
  253.                   return;
  254.         case 'i': if(!mcmp(n,"f")) error(216,p);
  255.                   if(!mcmp(n,"nt")) error(216,p);
  256.                   return;
  257.         case 'l': if(!mcmp(n,"ong")) error(216,p);
  258.                   return;
  259.         case 'r': if(!mcmp(n,"egister")) error(216,p);
  260.                   if(!mcmp(n,"eturn")) error(216,p);
  261.                   return;
  262.         case 's': if(!mcmp(n,"hort")) error(216,p);
  263.                   if(!mcmp(n,"igned")) error(216,p);
  264.                   if(!mcmp(n,"izeof")) error(216,p);
  265.                   if(!mcmp(n,"tatic")) error(216,p);
  266.                   if(!mcmp(n,"truct")) error(216,p);
  267.                   if(!mcmp(n,"witch")) error(216,p);
  268.                   return;
  269.         case 't': if(!mcmp(n,"ypedef")) error(216,p);
  270.                   return;
  271.         case 'u': if(!mcmp(n,"nion")) error(216,p);
  272.                   if(!mcmp(n,"nsigned")) error(216,p);
  273.                   return;
  274.         case 'v': if(!mcmp(n,"oid")) error(216,p);
  275.                   if(!mcmp(n,"olatile")) error(216,p);
  276.                   return;
  277.         case 'w': if(!mcmp(n,"hile")) error(216,p);
  278.                   return;
  279.         default : return;
  280.         }
  281.     }
  282. }
  283. void cpnum(char *m)
  284. /* kopiert die naechste int-Zahl von s nach m   */
  285. /* muss noch erheblich erweiter werden          */
  286. {
  287.     if(DEBUG&128) printf("Before cpnum:%s\n",s);
  288.     while(isdigit((unsigned char)*s)) *m++=*s++;
  289.     *m++=0;
  290.     if(DEBUG&128) printf("After cpnum:%s\n",s);
  291.  
  292. }
  293. static void killsp2(void)
  294. {
  295.     while(isspace((unsigned char)*s)) s++;
  296. }
  297. void killsp(void)
  298. /*  Ueberspringt Fuellzeichen                   */
  299. /*  noch einige unschoene Dinge drin            */
  300. {
  301.     int r;
  302.     if(DEBUG&128) printf("Before killsp:%s\n",s);
  303.     if(eof) raus();
  304.     while(isspace((unsigned char)*s)){
  305. /*        if(*s=='\n') {line++;if(DEBUG&1) printf("Line %d\n",line);}*/
  306.         s++;
  307.     }
  308.     if(*s==0){
  309.         do{
  310.             if(c_flags[17]&USEDFLAG) r=(fgets(string,MAXINPUT,in[0])!=0);
  311.                 else                 r=pp_nextline();
  312.             if(!r){
  313.                 /*raus();*/
  314.                 if(DEBUG&1) printf("nextline/fgets returned 0\n");
  315.                 s=string;*s=0;
  316.                 eof=1;
  317.                 return;
  318.             }else{
  319.                 line++;
  320.                 read_new_line=1;
  321.                 if(DEBUG&1) printf("Line %d\n",line);
  322.                 if(!strncmp("#pragma",string,7)){
  323.                     error(163);
  324.                     s=string+7;
  325.                     killsp2();
  326.                     if(!strncmp("opt",s,3)){
  327.                         s+=3;killsp2();
  328.                         c_flags_val[0].l=atol(s);
  329.                         if(DEBUG&1) printf("#pragma opt %ld\n",c_flags_val[0].l);
  330.                     }
  331.                     else if(!strncmp("printflike",s,10)){
  332.                         struct Var *v;
  333.                         s+=10;killsp2();
  334.                         cpbez(buff,0);
  335.                         if(DEBUG&1) printf("printflike %s\n",buff);
  336.                         v=find_var(buff,0);
  337.                         if(v){
  338.                             v->flags|=PRINTFLIKE;
  339.                             if(DEBUG&1) printf("succeeded\n");
  340.                         }
  341.                     }
  342.                     else if(!strncmp("scanflike",s,9)){
  343.                         struct Var *v;
  344.                         s+=9;killsp2();
  345.                         cpbez(buff,0);
  346.                         if(DEBUG&1) printf("scanflike %s\n",buff);
  347.                         v=find_var(buff,0);
  348.                         if(v){
  349.                             v->flags|=SCANFLIKE;
  350.                             if(DEBUG&1) printf("succeeded\n");
  351.                         }
  352.                     }
  353.                     else if(!strncmp("only-inline",s,11)){
  354.                         s+=11;killsp2();
  355.                         if(!strncmp("on",s,2)){
  356.                             if(DEBUG&1) printf("only-inline on\n");
  357.                             only_inline=1;
  358.                         }else{
  359.                             if(DEBUG&1) printf("only-inline off\n");
  360.                             only_inline=2;
  361.                         }
  362.                     }
  363.                     else if(!strncmp("type",s,4)){
  364.                     /*  Typ eines Ausdrucks im Klartext ausgeben    */
  365.                         np tree;
  366.                         s+=4;strcat(s,";");
  367.                         tree=expression();
  368.                         if(tree&&type_expression(tree)){
  369.                             printf("type of %s is:\n",string+7);
  370.                             prd(stdout,tree->ntyp);printf("\n");
  371.                         }
  372.                         if(tree) free_expression(tree);
  373.                     }
  374.                     else if(!strncmp("tree",s,4)){
  375.                     /*  gibt eine expression aus    */
  376.                         np tree;
  377.                         s+=4;strcat(s,";");
  378.                         tree=expression();
  379.                         if(tree&&type_expression(tree)){
  380.                             printf("tree of %s is:\n",string+7);
  381.                             pre(stdout,tree);printf("\n");
  382.                         }
  383.                         if(tree) free_expression(tree);
  384.                     }
  385.                 }
  386.                 if(string[0]=='#'&&isspace((unsigned char)string[1])&&isdigit((unsigned char)string[2])){
  387.                     sscanf(string+2,"%d \" %[^\"]",&line,errfname);
  388.                     if(DEBUG&1) printf("new line: %d (file=%s)\n",line,errfname);
  389.                     line--;
  390.                 }
  391.                 if(!strncmp("#line ",string,6)){
  392.                     sscanf(string+6,"%d \" %[^\"]",&line,errfname);
  393.                     if(DEBUG&1) printf("new line: %d (file=%s)\n",line,errfname);
  394.                     line--;
  395.                 }
  396.                 s=string;
  397.             }
  398.         }while(*s=='#');
  399.         killsp();
  400.     }
  401.     if(DEBUG&128) printf("After killsp:%s\n",s);
  402. }
  403. void enter_block(void)
  404. /*  Setzt Zeiger/Struckturen bei Eintritt in neuen Block    */
  405. {
  406.     if(nesting>=MAXN){error(9,nesting);return;}
  407.     nesting++;
  408.     if(DEBUG&1) printf("enter block %d\n",nesting);
  409.     first_ilist[nesting]=last_ilist[nesting]=0;
  410.     first_sd[nesting]=last_sd[nesting]=0;
  411.     first_si[nesting]=last_si[nesting]=0;
  412.     first_var[nesting]=last_var[nesting]=0;
  413.     if(nesting==1){
  414.         first_llist=last_llist=0;
  415.         first_clist=last_clist=0;
  416.         merk_varf=merk_varl=0;
  417.         merk_ilistf=merk_ilistl=0;
  418.         merk_sif=merk_sil=0;
  419. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  420. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  421. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  422. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  423. /*        merk_sdf=merk_sdl=0;*/
  424.         afterlabel=0;
  425.     }
  426. }
  427. void leave_block(void)
  428. /*  Setzt Zeiger/Struckturen bei Verlassen eines Blocks     */
  429. {
  430.     int i;
  431.     for(i=1;i<=MAXR;i++)
  432.         if(regbnesting[i]==nesting) regsbuf[i]=0;
  433.  
  434.     if(nesting<0){error(10);return;}
  435.     if(DEBUG&1) printf("leave block %d\n",nesting);
  436.     if(nesting>0){
  437.         if(merk_varl) merk_varl->next=first_var[nesting]; else merk_varf=first_var[nesting];
  438.         if(last_var[nesting]) merk_varl=last_var[nesting];
  439.         if(merk_sil) merk_sil->next=first_si[nesting]; else merk_sif=first_si[nesting];
  440.         if(last_si[nesting]) merk_sil=last_si[nesting];
  441.         if(merk_sdl) merk_sdl->next=first_sd[nesting]; else merk_sdf=first_sd[nesting];
  442.         if(last_sd[nesting]) merk_sdl=last_sd[nesting];
  443.         if(merk_ilistl) merk_ilistl->next=first_ilist[nesting]; else merk_ilistf=first_ilist[nesting];
  444.         if(last_ilist[nesting]) merk_ilistl=last_ilist[nesting];
  445.     }
  446.     if(nesting==1){
  447.         if(merk_varf) gen_vars(merk_varf);
  448.         if(first_llist) free_llist(first_llist);
  449.         if(first_clist) free_clist(first_clist);
  450.         if(merk_varf) free_var(merk_varf);
  451.         if(merk_sif) free_si(merk_sif);
  452. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  453. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  454. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  455. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  456. /*        if(merk_sdf) free_sd(merk_sdf);*/
  457.         if(merk_ilistf) free_ilist(merk_ilistf);
  458.     }
  459.     if(nesting==0){
  460. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  461. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  462. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  463. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  464.         if(merk_sdf) free_sd(merk_sdf);
  465.         if(first_var[0]) gen_vars(first_var[0]);
  466.         if(first_var[0]) free_var(first_var[0]);
  467.         if(first_sd[0]) free_sd(first_sd[0]);
  468.         if(first_si[0]) free_si(first_si[0]);
  469.         if(first_ilist[0]) free_ilist(first_ilist[0]);
  470.     }
  471.     nesting--;
  472. }
  473. void pra(FILE *f,struct argument_list *p)
  474. /*  Gibt argument_list umgekehrt auf Bildschirm aus             */
  475. {
  476.     if(p->next){ pra(f,p->next);fprintf(f,",");}
  477.     if(p->arg) pre(f,p->arg);
  478. }
  479. void pre(FILE *f,np p)
  480. /*  Gibt expression auf Bildschirm aus                          */
  481. {
  482.     int c;
  483.     c=p->flags;
  484.     if(p->sidefx) fprintf(f,"/");
  485.     if(p->lvalue) fprintf(f,"|");
  486.     if(c==CALL){fprintf(f,"call-function(");pre(f,p->left);fprintf(f,")(");
  487.                 if(p->alist) pra(f,p->alist);
  488.                 fprintf(f,")");return;}
  489.     if(c==CAST){fprintf(f,"cast(");pre(f,p->left);
  490.                 fprintf(f,"->");prd(f,p->ntyp);
  491.                 fprintf(f,")");return;}
  492.     if(c==MEMBER){if(p->identifier) fprintf(f,".%s",p->identifier);return;}
  493.     if(c==IDENTIFIER){if(p->identifier) fprintf(f,"%s",p->identifier);
  494.         fprintf(f,"+");printval(f,&p->val,LONG,1); return;}
  495.     fprintf(f,"%s(",ename[c]);
  496.     if(p->left) pre(f,p->left);
  497.     if(p->right){
  498.         fprintf(f,",");
  499.         pre(f,p->right);
  500.     }
  501.     fprintf(f,")");
  502.     if(c==CEXPR||c==PCEXPR){fprintf(f,"(value="); printval(f,&p->val,p->ntyp->flags,1); fprintf(f,")");}
  503. }
  504.  
  505. void error(int errn,...)
  506. /*  Behandelt Ausgaben wie Fehler und Meldungen */
  507. {
  508.     int type;
  509.     va_list vl;char *errstr="",*txt;
  510.     if(errn==-1) errn=158;
  511.     type=err_out[errn].flags;
  512.     if(type&DONTWARN) return;
  513.     va_start(vl,errn);
  514.     if(type&WARNING) errstr="warning";
  515.     if(type&ERROR) errstr="error";
  516.     if(type&NOLINE){
  517.         printf("%s %d: ",errstr,errn);
  518.     }else if(type&INFUNC){
  519.         if((type&INIC)&&err_ic&&err_ic->line){
  520.             if(!(c_flags[17]&USEDFLAG)) txt=filename[incnesting];
  521.                 else txt=errfname;
  522.             printf("%s %d in line %d of \"%s\": ",errstr,errn,err_ic->line,txt);
  523.         }else{
  524.             printf("%s %d in function \"%s\": ",errstr,errn,cur_func);
  525.         }
  526.     }else{
  527.         int n;
  528.         {if(eof) printf(">EOF\n"); else printf(">%s",string);}
  529.         if(!(c_flags[17]&USEDFLAG)){
  530.             printf("\n");
  531.             n=linenr;txt=filename[incnesting];
  532.         }else{
  533.             n=line;txt=errfname;
  534.         }
  535.         if(c_flags[20]&USEDFLAG){   /*  strip-path from filename */
  536.             char *p=txt,c;
  537.             while(c=*p++)
  538.                 if(c==':'||c=='/'||c=='\\') txt=p;
  539.         }
  540.         printf("%s %d in line %d of \"%s\": ",errstr,errn,n,txt);
  541.     }
  542.     vprintf(err_out[errn].text,vl);
  543.     printf("\n");
  544.     va_end(vl);
  545.     if(type&ERROR){
  546.         errors++;
  547.         if(c_flags_val[8].l&&c_flags_val[8].l<=errors)
  548.             {printf("Maximum number of errors reached!\n");raus();}
  549.     }
  550.     if(type&FATAL){printf("aborting...\n");raus();}
  551. }
  552. FILE *open_out(char *name,char *ext)
  553. /*  Haengt ext an name an und versucht diese File als output zu oeffnen */
  554. {
  555.     char *s,*p;FILE *f;
  556.     if(ext){
  557.         s=mymalloc(strlen(name)+strlen(ext)+2);
  558.         strcpy(s,name);
  559.         p=s+strlen(s);
  560.         while(p>=s){
  561.             if(*p=='.'){*p=0;break;}
  562.             p--;
  563.         }
  564.         strcat(s,".");
  565.         strcat(s,ext);
  566.     }else s=name;
  567.     f=fopen(s,"w");
  568.     if(!f) printf("Couldn't open <%s> for output!\n",s);
  569.     if(ext) free(s);
  570.     return(f);
  571. }
  572.